﻿
using Sys;

using System.Silverlight;
using System.Silverlight.Presentation;
using System.Silverlight.Presentation.Animation;
using System;

using seh = Sys.EventHandler;
using sea = Sys.EventArgs;

namespace SBT
{

    public class FlowPanel : AgLayoutManager
    {
        private seh m_childSizeChangedHandler;

        protected override void OnUIElementAdded(UIElement item)
        {
            base.OnUIElementAdded(item);
            if (IsInitialized)
            {
                AgBehavior behavior = AgBehavior.FindBehaviorByUIElement(item);
                if (!(bool)(object)behavior)
                {
                    behavior = new AgBehavior();
                    behavior.Element = item;
                    behavior.Plugin = Plugin;
                    behavior.Initialize();
                }

                behavior.add_widthChanged(m_childSizeChangedHandler);
                behavior.add_heightChanged(m_childSizeChangedHandler);
            }
        }
        protected override void OnUIElementRemoved(UIElement item)
        {
            base.OnUIElementRemoved(item);
            if (IsInitialized)
            {
                AgBehavior behavior = AgBehavior.FindBehaviorByUIElement(item);
                if (!(bool)(object)behavior)
                {
                    behavior = new AgBehavior();
                    behavior.Element = item;
                    behavior.Plugin = Plugin;
                    behavior.Initialize();
                }
                behavior.remove_widthChanged(m_childSizeChangedHandler);
                behavior.remove_heightChanged(m_childSizeChangedHandler);
            
            }
        }
        
        public override void Initialize()
        {
            base.Initialize();
            m_childSizeChangedHandler = OnChildSizeChanged;
            seh sizeChangedHandler = delegate { InvalidateLayout(); };
            this.add_heightChanged(sizeChangedHandler);
            this.add_widthChanged(sizeChangedHandler);
            for (int i = 0; i < UnderlyingCanvas.Children.Count; i++)
            {
                UIElement item = UnderlyingCanvas.Children.GetItem(i);
                AgBehavior behavior = AgBehavior.FindBehaviorByUIElement(item);
                if (!(bool)(object)behavior)
                {
                    behavior = new AgBehavior();
                    behavior.Element = item;
                    behavior.Plugin = Plugin;
                    behavior.Initialize();
                }
                behavior.add_widthChanged(m_childSizeChangedHandler);
                behavior.add_heightChanged(m_childSizeChangedHandler);
            
            }
        }
        
        public FlowPanel()
        {
            
        }
        //protected override void OnHeightChanged()
        //{
        //    InvalidateLayout();
        //    base.OnHeightChanged();
        //}
        //protected override void OnWidthChanged()
        //{
        //    InvalidateLayout();
        //    base.OnWidthChanged();
        //}
        private bool m_layouting = false;
        public override void InvalidateLayout()
        {
            if (!m_layouting)
            {
                m_layouting = true;
                base.InvalidateLayout();
                double offsetX = 0;
                double offsetY = 0;
                double maxLineHeight = 0;
                for (int i = 0; i < UnderlyingCanvas.Children.Count; i++)
                {


                    UIElement element = UnderlyingCanvas.Children.GetItem(i);
                    AgBehavior behavior = AgBehavior.FindBehaviorByUIElement(element);
                    if (!(bool)(object)behavior)
                    {
                        behavior = new AgBehavior();
                        behavior.Element = element;
                        behavior.Plugin = Plugin;
                        behavior.Initialize();
                    }
                    if (element.Visibility == Visibility.Visible)
                    {
                        if (behavior != null)
                        {
                            behavior.Top = offsetY;
                            behavior.Left = offsetX;

                            if (behavior.Width > Width)
                                behavior.Width = Width;

                            if (offsetX + behavior.Width > Width)
                            {
                                offsetY += maxLineHeight;
                                maxLineHeight = 0;
                                behavior.Left = 0;
                                behavior.Top = offsetY;
                                offsetX = behavior.Width;
                            }
                            else
                            {
                                maxLineHeight = Math.Max(behavior.Height, maxLineHeight);
                                offsetX += behavior.Width;
                            }
                        }
                        else
                        {
                            element.SetValue("Canvas.Left", offsetX);
                            element.SetValue("Canvas.Top", offsetY);

                            double eWidth = element.Width;
                            double eHeight = element.Height;

                            TextBlock elementTmp = null;
                            try
                            {
                                elementTmp = (TextBlock)element;
                                eWidth = elementTmp.ActualWidth;
                                eHeight = elementTmp.ActualHeight - (2 * (elementTmp.FontSize / 3));
                                element.SetValue("Canvas.Top", offsetY - (elementTmp.FontSize / 3));
                            }
                            catch { }

                            if (eWidth > Width)
                                eWidth = Width;

                            if (offsetX + eWidth > Width)
                            {
                                offsetY += maxLineHeight;
                                maxLineHeight = 0;
                                element.SetValue("Canvas.Left", 0);
                                element.SetValue("Canvas.Top", offsetY);
                                if (elementTmp != null)
                                    element.SetValue("Canvas.Top", offsetY - (elementTmp.FontSize / 3));
                                offsetX = eWidth;
                            }
                            else
                            {
                                maxLineHeight = Math.Max(eHeight, maxLineHeight);
                                offsetX += eWidth;
                            }
                        }
                        //DBounds bounds = GetItemBounds(i);
                        //if (Orientation == Orientation.Horizontal)
                        //    offset += bounds.Width;
                        //else
                        //    offset += bounds.Height;

                    }
                }
                this.Height = maxLineHeight + offsetY;
                m_layouting = false;
            }
        }
        private void OnChildSizeChanged(object sender, sea args)
        {
            InvalidateLayout();
        }
        
    }
}